#!/usr/bin/env python
# A collection of my simplified html functions
import re

(OPENTAG, CLOSETAG) = range(2)

TAG_COMMON_FLAGS = re.IGNORECASE | re.DOTALL

def find_tag_by_str(text, tag, str, tagtype):
    """Search string 'str' in all tags 'tag' in 'text' and return all re matches.
    Tagtype is OPENTAG or CLOSETAG, OPENTAG is like '<a ....> ... </a>'
    CLOSETAG is like '<img ....>'
    Only return the most inner level matches for OPENTAG type of tags.
    """
    if tagtype == OPENTAG:
        # Use backreferencing to find only the inner level of tag contexts
        pattern = re.compile('<' + tag + '(?:(?!</?' + tag + '>).)*' + str + '(?:(?!</?' + tag + '>).)*</' + tag + '>', TAG_COMMON_FLAGS)
    else:
        pattern = re.compile('<' + tag + r'\b[^<>]*' + str + '[^<>]*>', TAG_COMMON_FLAGS)
    
    return re.findall(pattern, text)

def find_property_in_tag_by_str(property, text, tag, str, tagtype, all=False):
    """ First use find_tag_by_str to find the tag, then match and extract the specified property.
    Returns all matches as a list if parameter 'all' is True
    """
    result = []

    found = find_tag_by_str(text, tag, str, tagtype)
    for item in found:
        patterns = [re.compile('<' + tag + r'\b[^<>]*\b' + property + '="([^"<>]+?)"[^>]*>', TAG_COMMON_FLAGS),
                    re.compile('<' + tag + r'\b[^<>]*\b' + property + "='([^'<>]+?)'[^>]*>", TAG_COMMON_FLAGS)]
        for pattern in patterns:
            m = re.search(pattern, item)
            if m:
                result.append(m.group(1))

    if all:
        return result
    elif result:
        return result[0]

def find_content_in_tag_by_str(text, tag, str, all=False):
    """ First use find_tag_by_str to find the tag, then extract the content of the tag.
    Returns all matches as a list if parameter 'all' is True
    """
    result = []

    found = find_tag_by_str(text, tag, str, OPENTAG)
    for item in found:
        pattern = re.compile('<' + tag + r'\b[^<>]*>(.+)</' + tag + '>', TAG_COMMON_FLAGS)
        m = re.search(pattern, item)
        if m:
            result.append(m.group(1))

    if all:
        return result
    elif result:
        return result[0]

def find_link_with_str(text, str, all=False):
    return find_property_in_tag_by_str("href", text, "a", str, OPENTAG, all)

def find_imgsrc_with_str(text, str, all=False):
    return find_property_in_tag_by_str("src", text, "img", str, CLOSETAG, all)

if __name__ == '__main__':

    T = "<a href=\"http://abc.com/ok.img\"> sdf asdf sf hello world asdfas </a>"
    T1 = "<a base=\"hello\" style='ok' href=\"http://abc.com/ok.img\"> sdf asdf sf hello world asdfas </a><img class='preview' style='border: 1px solid black;' src='http://interfacelift.com/wallpaper/previews/01461_sunnyhighlands.jpg' alt='Sunny Highlands wallpaper' width='240' height='150' />"
    T2 = '<div class="sm-wallpaper-link">\r\n<a href="/staticfiles/NGS/Shared/StaticFiles/Photography/Images/POD/b/blooming-trees-dominica-90466-lw.jpg"><img align="absmiddle" border="0" alt="Icon: larger resolution" height="27" width="37" src="/staticfiles/NGS/Global/ApplicationAssets/img/art-icon-wallpaper-1024.gif"></a><a href="/staticfiles/NGS/Shared/StaticFiles/Photography/Images/POD/b/blooming-trees-dominica-90466-lw.jpg">1024 x 768 pixels&#151;best for larger monitors</a>\n</div>'
    T3 = '<rss version="2.0"><channel><title>NASA Image of the Day</title><link>http://www.nasa.gov/multimedia/imagegallery/index.html</link><description>The latest NASA "Image of the Day" image.</description><language>en-us</language><docs>http://blogs.law.harvard.edu/tech/rss</docs><managingEditor>cenger@nasa.gov</managingEditor><webMaster>brian.dunbar@nasa.gov</webMaster><image xmlns:java_code="xalan://gov.nasa.build.Utils1"> <url>http://www.nasa.gov/images/content/218145main_image_1043_516-387.jpg</url> <title>Out on a Limb</title> <link>http://www.nasa.gov/multimedia/imagegallery/index.html</link> <description/> </image> <item xmlns:java_code="xalan://gov.nasa.build.Utils1"> <title>Out on a Limb</title> <link>http://www.nasa.gov/multimedia/imagegallery/image_feature_1043.html</link> <description>Anchored to a Canadarm2 mobile foot restraint, astronaut Rick Linnehan participates in the mission\'s first scheduled spacewalk</description> <guid isPermaLink="true">http://www.nasa.gov/multimedia/imagegallery/image_feature_1043.html</guid> <pubDate>Wed, 19 Mar 2008 00:00:00 EDT</pubDate> </item></channel></rss>'
    T4 = '<div class="content"><p>some text</p>\n<img src="test.jpg"></div>'

    print "Testing find_tag_by_str"
    found = find_tag_by_str(T4, "div", 'class="content"', OPENTAG)
    assert(found[0] == T4)

    print "Testing find_link_with_content"
    assert(find_link_with_str(T, "hello world") == "http://abc.com/ok.img")
    assert(find_link_with_str(T, "good bye") == None)
    assert(find_link_with_str(T1, "hello world") == "http://abc.com/ok.img")
    assert(find_link_with_str(T2, "1024 x 768") == "/staticfiles/NGS/Shared/StaticFiles/Photography/Images/POD/b/blooming-trees-dominica-90466-lw.jpg")
    print "pass"

    print "Testing find_content_in_tag_by_str"
    assert(find_content_in_tag_by_str(T3, "url", "/images/content") == "http://www.nasa.gov/images/content/218145main_image_1043_516-387.jpg")
    assert(find_content_in_tag_by_str(T3, "item", "Out on a Limb") == ' <title>Out on a Limb</title> <link>http://www.nasa.gov/multimedia/imagegallery/image_feature_1043.html</link> <description>Anchored to a Canadarm2 mobile foot restraint, astronaut Rick Linnehan participates in the mission\'s first scheduled spacewalk</description> <guid isPermaLink="true">http://www.nasa.gov/multimedia/imagegallery/image_feature_1043.html</guid> <pubDate>Wed, 19 Mar 2008 00:00:00 EDT</pubDate> ')
    assert(find_content_in_tag_by_str(T4, "div", 'class="content"') == '<p>some text</p>\n<img src="test.jpg">')
    print "pass"

    print "Testing find_property_in_tag_by_str"
    assert(find_property_in_tag_by_str("style", T1, "a", "hello", OPENTAG) == "ok")
    assert(find_property_in_tag_by_str("base", T1, "a", "hello", OPENTAG) == "hello")
    assert(find_property_in_tag_by_str("no_exist", T1, "a", "hello", OPENTAG) == None)
    assert(find_property_in_tag_by_str("src", T1, "img", "/wallpaper/previews/", CLOSETAG) == 'http://interfacelift.com/wallpaper/previews/01461_sunnyhighlands.jpg')
    print "pass"

    print "Testing find_content_in_tag_by_str all"
    assert(find_content_in_tag_by_str(T3, "title", "", True) == ['NASA Image of the Day', 'Out on a Limb', 'Out on a Limb'])
    print "pass"